package api

import (
	"encoding/json"
	"fmt"
	"log"
	"net/http"
	"sync"
	"time"

	"github.com/gin-gonic/gin"
	"github.com/gorilla/websocket"
)

/**
WebSocket消息格式:
{
    "cmd": "online"
}

{
    "cmd":"send_message",
    "data":{
        "match_id": 123,
        "content":"hello",
        "msg_type": 1
    }
}

{
    "cmd":"join_chat",
    "data":{
        "match_id": 123
    }
}
*/

// 全局WebSocket连接管理
var (
	userMutex sync.RWMutex
)

type WSReq struct {
	Cmd  string      `json:"cmd"`
	Data interface{} `json:"data"`
}

//type WSResp struct {
//	Code int         `json:"code"`
//	Msg  string      `json:"msg"`
//	Data interface{} `json:"data"`
//}

// 发送消息结构体
type SendMessageData struct {
	MatchId int64  `json:"match_id"`
	Content string `json:"content"`
	MsgType int32  `json:"msg_type"` // 1:文本 2:图片 3:语音
}

type WSSendMessageReq struct {
	Cmd  string          `json:"cmd"`
	Data SendMessageData `json:"data"`
}

// 加入聊天结构体
type JoinChatData struct {
	MatchId int64 `json:"match_id"`
}

type WSJoinChatReq struct {
	Cmd  string       `json:"cmd"`
	Data JoinChatData `json:"data"`
}

func Chat(c *gin.Context) {
	// 获取用户ID - 从URL参数或Header中获取
	userIdStr := c.Query("userId")
	if userIdStr == "" {
		userIdStr = c.Query("userid")
	}
	if userIdStr == "" {
		userIdStr = c.GetHeader("User-ID")
	}

	if userIdStr == "" {
		c.JSON(http.StatusUnauthorized, gin.H{
			"code": -1,
			"msg":  "缺少用户ID参数",
			"data": nil,
		})
		return
	}

	// 转换为int64
	var userId int64
	_, err := fmt.Sscanf(userIdStr, "%d", &userId)
	if err != nil || userId <= 0 {
		c.JSON(http.StatusBadRequest, gin.H{
			"code": -1,
			"msg":  "无效的用户ID",
			"data": nil,
		})
		return
	}

	// 升级到WebSocket连接
	var upgrader = websocket.Upgrader{
		CheckOrigin: func(r *http.Request) bool {
			return true // 允许跨域
		},
	}

	conn, err := upgrader.Upgrade(c.Writer, c.Request, nil)
	if err != nil {
		log.Print("upgrade:", err)
		c.JSON(http.StatusOK, gin.H{
			"code": -1,
			"msg":  "websocket连接失败",
			"data": nil,
		})
		return
	}

	defer func() {
		// 用户下线时清理连接
		Offline(userId)
		conn.Close()
	}()

	// 用户上线
	Online(userId, conn)

	for {
		_, message, err := conn.ReadMessage()
		if err != nil {
			log.Println("read:", err)
			break
		}

		var req WSReq
		err = json.Unmarshal(message, &req)
		if err != nil {
			WSRespErr(conn, 1000, "JSON格式错误")
			continue
		}

		switch req.Cmd {
		case "online":
			// 用户上线确认
			WSRespSuccess(conn, map[string]interface{}{
				"user_id": userId,
				"status":  "online",
			})
		case "send_message":
			// 发送聊天消息
			go SendChatMessage(conn, message, userId)
		case "join_chat":
			// 加入聊天室
			go JoinChat(conn, message, userId)
		default:
			WSRespErr(conn, 10001, "不支持的命令")
		}
	}
}

// 用户上线
func Online(userId int64, conn *websocket.Conn) {
	userMutex.Lock()
	defer userMutex.Unlock()
	OnlineUser[uint(userId)] = conn
	log.Printf("用户 %d 已上线", userId)
}

// 用户下线
func Offline(userId int64) {
	userMutex.Lock()
	defer userMutex.Unlock()
	delete(OnlineUser, uint(userId))
	log.Printf("用户 %d 已下线", userId)
}

// 发送聊天消息
func SendChatMessage(conn *websocket.Conn, message []byte, senderId int64) {
	var req WSSendMessageReq
	err := json.Unmarshal(message, &req)
	if err != nil {
		WSRespErr(conn, 20001, "消息格式错误")
		return
	}

	// 验证参数
	if req.Data.MatchId <= 0 {
		WSRespErr(conn, 20002, "无效的匹配ID")
		return
	}
	if req.Data.Content == "" {
		WSRespErr(conn, 20003, "消息内容不能为空")
		return
	}
	if req.Data.MsgType < 1 || req.Data.MsgType > 3 {
		req.Data.MsgType = 1 // 默认为文本消息
	}

	// 使用本地处理发送消息
	log.Printf("使用本地处理发送消息")

	// 模拟消息ID
	messageId := int64(time.Now().UnixNano())

	// 发送消息给接收者（如果在线）
	go sendMessageToReceiver(req.Data.MatchId, senderId, map[string]interface{}{
		"message_id": messageId,
		"match_id":   req.Data.MatchId,
		"sender_id":  senderId,
		"content":    req.Data.Content,
		"msg_type":   req.Data.MsgType,
		"timestamp":  time.Now().Unix(),
	})

	// 返回成功响应
	WSRespSuccess(conn, map[string]interface{}{
		"message_id": messageId,
		"match_id":   req.Data.MatchId,
		"content":    req.Data.Content,
		"msg_type":   req.Data.MsgType,
		"status":     "sent",
		"timestamp":  time.Now().Unix(),
	})
}

// 加入聊天室
func JoinChat(conn *websocket.Conn, message []byte, userId int64) {
	var req WSJoinChatReq
	err := json.Unmarshal(message, &req)
	if err != nil {
		WSRespErr(conn, 30001, "消息格式错误")
		return
	}

	// 验证匹配ID
	if req.Data.MatchId <= 0 {
		WSRespErr(conn, 30002, "无效的匹配ID")
		return
	}

	// 这里应该验证用户是否有权限加入该聊天室
	// 暂时返回成功响应
	WSRespSuccess(conn, map[string]interface{}{
		"match_id": req.Data.MatchId,
		"status":   "joined",
	})
}

func WSRespErr(conn *websocket.Conn, code int, msg string) {
	response := WSResp{
		Code: uint(code),
		Msg:  msg,
		Data: nil,
	}

	responseStr, _ := json.Marshal(response)

	err := conn.WriteMessage(websocket.TextMessage, responseStr)
	if err != nil {
		log.Println("write:", err)
	}
}

// 发送消息给接收者
func sendMessageToReceiver(matchId, senderId int64, messageData map[string]interface{}) {
	receiverId := findReceiverByMatchId(matchId, senderId)
	if receiverId == 0 {
		log.Printf("无法找到匹配ID %d 的接收者", matchId)
		return
	}

	// 通过WebSocket连接直接发送消息
	userMutex.RLock()
	if conn, exists := OnlineUser[uint(receiverId)]; exists {
		// 构建WebSocket消息格式
		wsMessage := map[string]interface{}{
			"type": "new_message",
			"data": messageData,
		}

		WSRespSuccess(conn, wsMessage)
		log.Printf("消息已通过WebSocket发送给接收者%d", receiverId)
	} else {
		log.Printf("接收者%d不在线，消息已保存到数据库", receiverId)
	}
	userMutex.RUnlock()
}

// 根据匹配ID找到接收者ID
func findReceiverByMatchId(matchId, senderId int64) int64 {
	// 简化实现：假设匹配ID就是接收者ID
	// 在实际应用中，这里应该查询数据库获取匹配详情
	receiverId := matchId % 1000000 // 简单的模拟逻辑

	if receiverId == senderId {
		// 如果计算出的接收者ID和发送者ID相同，则使用另一个ID
		receiverId = (matchId + 1) % 1000000
	}

	log.Printf("找到匹配ID %d 的接收者: %d (发送者: %d)", matchId, receiverId, senderId)

	return receiverId
}

func WSRespSuccess(conn *websocket.Conn, data interface{}) {
	response := WSResp{
		Code: 0,
		Msg:  "ok",
		Data: data,
	}

	responseStr, _ := json.Marshal(response)

	err := conn.WriteMessage(websocket.TextMessage, responseStr)
	if err != nil {
		log.Println("write:", err)
	}
}

// 发送匹配成功通知
func SendMatchNotification(userId1, userId2, matchId int64) {
	// 构建匹配通知消息
	matchNotification := map[string]interface{}{
		"type": "match_success",
		"data": map[string]interface{}{
			"match_id":  matchId,
			"message":   "恭喜！你们互相喜欢，匹配成功！",
			"timestamp": time.Now().Unix(),
		},
	}

	// 发送给两个用户
	userMutex.RLock()
	if conn1, exists := OnlineUser[uint(userId1)]; exists {
		WSRespSuccess(conn1, matchNotification)
		log.Printf("匹配通知已发送给用户%d", userId1)
	}
	if conn2, exists := OnlineUser[uint(userId2)]; exists {
		WSRespSuccess(conn2, matchNotification)
		log.Printf("匹配通知已发送给用户%d", userId2)
	}
	userMutex.RUnlock()
}
